﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace Microsoft.JCI.Service.TaskAgent
{
    public class SmsProcess
    { 
        
        private int ThreadCount;
        private bool IsRunning;
        private List<System.Threading.Thread> ThreadList;   //线程列表
        private Queue<DataRow> MessageQueue;    //邮件队列
        private static object LockKey = new object();  //用于控制多线程并发
        private int ReadMailInterval = 30000; //邮件队列更新时间间隔30秒
        private int SendMailInterval = 2000; //邮件队列发送邮件时间间隔3秒
        private int MsgQueueLenght = 100; //邮件队列长度

        public SmsProcess(int threadCount)
        {
            this.ThreadCount = threadCount;
            this.ThreadList = new List<System.Threading.Thread>();

            //添加获取数据线程
            this.ThreadList.Add(new System.Threading.Thread(GetMessageQueue));

            //添加发邮件线程
            for (int i = 0; i < threadCount; i++)
            {
                this.ThreadList.Add(new System.Threading.Thread(SendMail));
            }

            MessageQueue = new Queue<DataRow>();
        }

        public void Start()
        {
            if (IsRunning)
                return;

            IsRunning = true;
            foreach (System.Threading.Thread thread in this.ThreadList)
            {
                //启动所有线程
                thread.Start();
                System.Threading.Thread.Sleep(100);
            }
        }

        public void Sotp()
        {
            IsRunning = false;

            System.Threading.Thread.Sleep(1000);

            foreach (System.Threading.Thread thread in this.ThreadList)
            {
                try
                {
                    thread.Abort();
                }
                catch
                {
                }

            }
        }


        /// <summary>
        /// 邮件队列中没有邮件时从数据库中获取邮件，并放入邮件队列中；
        /// </summary>
        private void GetMessageQueue()
        {
            while (IsRunning)
            {
                try
                {

                    lock (LockKey)
                    {
                        if (MessageQueue.Count <= 0)
                        {
                            //获取新的邮件
                            DataTable table = MailHelper.GetMailMessages(MsgQueueLenght);
                            if (table != null)
                            {
                                for (int i = 0; i < table.Rows.Count; i++)
                                {
                                    //增加邮件队列
                                    MessageQueue.Enqueue(table.Rows[i]);
                                }
                            }
                        }

                    }

                    //取邮件间隔
                    System.Threading.Thread.Sleep(ReadMailInterval);

                }
                catch (Exception ex)
                {
                     
                }
            }

        }

        /// <summary>
        /// 邮件发送线程处理函数，基本思路为：
        /// 2、正在发送的邮件放在发送列表中，需要保证这些邮件不会被再次从数据库中取出
        /// 3、邮件发送成功需要更新邮件发送状态到数据库中
        /// 4、无论邮件是否发送成功，都需要将邮件从发送列表中去除
        /// </summary>
        private void SendMail()
        {
            while (IsRunning)
            {
                try
                {
                    DataRow row = null;

                    //从邮件队列中获取邮件
                    lock (LockKey)
                    {
                        if (MessageQueue.Count > 0)
                        {
                            row = MessageQueue.Dequeue();
                        }
                    }

                    if (row != null)
                    {
                        bool isSuccessful = false;
                        try
                        {
                            //send email

                            Guid msgId = (Guid)row["MailMsgID"];
                            List<MailAttachment> AttaList = MailHelper.GetMailAttachments(msgId);
                            isSuccessful = MailSender.SendEmail(
                                row["Receivers"].ToString(),
                                row["ReceiverDisplayName"].ToString(),
                                row["CCReceivers"].ToString(),
                                row["CCReceiverDisplayName"].ToString(),
                                row["Subject"].ToString(),
                                row["Body"].ToString(), AttaList);

                            if (isSuccessful)
                            {
                                MailHelper.UpdateMessageStatus(msgId, MailHelper.MailStatus.Sucess);
                            }
                            else
                            {
                                MailHelper.UpdateMessageStatus(msgId, MailHelper.MailStatus.Failed);

                            }

                        }
                        catch (Exception ee)
                        {
                            //出现异常 记录事件日志
                           
                        }

                        //发送邮件时间间隔
                        System.Threading.Thread.Sleep(SendMailInterval);

                    }
                    else
                    {
                        //如果有没有数据等待时间间隔
                        System.Threading.Thread.Sleep((int)ReadMailInterval / (2 * ThreadCount));
                    }
                }
                catch (Exception ex)
                {
                    
                }
            }
        }
    }
}
